Naming
------

<op><suffix1>_<suffix2>

    suffix1: refers to inputs
    suffix2: refers to arguments

    f/s/u/i/r   float/signed/unsigned/any integer/raw, default: any integer for input, unsigned for arguments
    8/16/32/64  size, default: 32 for input, 8 for arguments

add         add two 32 bit integer (signedness is irrelevant for add/sub/mul)
addf64      add two 64 bit floats
cmpi64      compare to 32 bit integer


Argument order
--------------

Arguments get pushed in reverse order, so first argument is pushed last and popped first by the instruction reading it.

push_const 2
push_const 1
cmp_igt         // 2 > 1 ?
print           // 0


fn jmp_igt(vm: &mut Self, addr: u32) {
    let a = vm.stack.pop().unwrap();
    let b = vm.stack.pop().unwrap();
    if a < b {
        vm.pc = addr as usize;
    }
}